django 视图函数
[toc]
3.视图函数
3.1 request对象
request.path #request.path当前请求路径
request.method #当前请求方法(get,post...)
request.GET #获取所有get请求携带过来的数据
request.POST #获取所有post请求携带过来的数据
request.body #获取所有post请求携带过来的数据的原始格式
3.2 视图函数使用小示例
urls文件
urlpatterns = [
url(r'^admin/', admin.site.urls),
#编写一个login登陆视图文件
url(r'^login/', views.login),
]
views文件
from django.shortcuts import render,HttpResponse
def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'admin' and pwd == 'admin':
return HttpResponse('登陆成功!')
else:
return HttpResponse('登陆失败!!!')
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{#<form action="">#}
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" value="登陆">
</form>
</body>
</html>
为了验证post请求,注释settings文件中的一行
Django项目下同名目录中的settings文件,48行
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
浏览器访问
错误的示例
urls文件
def login(request):
if request.method == 'POST':
return render(request,'login.html')
else:
uname = request.GET.get('username')
pwd = request.GET.get('password')
if uname == 'admin' and pwd == 'admin':
return HttpResponse('登陆成功!')
else:
return HttpResponse('登陆失败!!!')
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#<这里指定提交请求方法为post>#}
<form action="" method="post">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" value="登陆">
</form>
</body>
</html>
为了验证post请求,注释settings文件中的一行
Django项目下同名目录中的settings文件,48行
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
按照之前的理解应该是会返回登陆界面,因为我login.html文件中form表单写的请求方法是post,而views视图文件中的逻辑判断是如果请求是post则返回登陆界面,但是实际情况并不是这样
为什么会直接返回登陆失败呢?
原因:当浏览器打开页面的时候,默认的方法就是GET,当点击登陆那一刻才会根据form表单中的method指定的请求类型而进行转变,但是现在直接就是GET方法,因此在login函数的判断中就直接跳到了第一个else后面,但是此时根本就没有用户登陆界面出现,所以就无法获取用户名和密码,所以会直接提示登陆失败!!!
3.3 响应方法
- render返回html页面
- HttpResponse返回字符串
- redirect
3.3.1render 返回html页面
views文件中的写法
#需要导入HttpResponse
from django.shortcuts import render,HttpResponse
# Create your views here.
def index(request):
return render(request,'index.html')
3.3.2 HttpResponse 返回字符串
views文件中的写法
#需要导入HttpResponse
from django.shortcuts import render,HttpResponse
# Create your views here.
#HttpResponse方法中直接写字符串
def index(request):
# return render(request,'index.html')
return HttpResponse('HttpResponse方法返回 的是字符串')
3.3.3 redirect 重定向
FBV写法
urls文件
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^home/', views.home),
url(r'^login/', views.login),
]
views文件
#redirect方法需要导入redirect
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def home(request):
return HttpResponse('登陆成功')
def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
uname = request.POST.get('uname')
pwd = request.POST.get('pwd')
if uname == 'admin' and pwd == 'admin':
# return HttpResponse('登陆成功')
return redirect('/home/')
else:
# return HttpResponse('登陆失败')
return redirect('/login/')
redict是重定向,之前我们访问的时候如果登陆失败就直接提示登陆失败
现在使用了redict重定向
如果登陆成功就重定向到另一个路径下,这里是/home,也就是登陆成功页面
如果登陆失败就还是重定向到访问路径下,这里是/login,也就是登陆界面
CBV写法
urls文件
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^login/', views.login),
url(r'^login/', views.LoginView.as_view()),
]
views文件
#redirect方法需要导入redirect
from django.shortcuts import render,HttpResponse,redirect
from django.views import View #CBV写法中需要导入View
# Create your views here.
def home(request):
return HttpResponse('登陆成功')
class LoginView(View):
def get(self,request):
return render(request, 'login.html')
def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'admin' and pwd == 'admin':
# return HttpResponse('登陆成功')
return redirect('/home/')
else:
# return HttpResponse('登陆失败')
return redirect('/login/')
redict是重定向,之前我们访问的时候如果登陆失败就直接提示登陆失败
现在使用了redict重定向
如果登陆成功就重定向到另一个路径下,这里是/home,也就是登陆成功页面
如果登陆失败就还是重定向到访问路径下,这里是/login,也就是登陆界面
3.4 CBV和FBV
3.4.1含义
- FBV:function based view :基于函数的视图逻辑
- CBV:class based view :基于类的视图逻辑
3.4.2 CBV
CBV中url写法
# url(r'^login/', views.login),
url(r'^login/', views.LoginView.as_view()),
CBV中views写法
from django.shortcuts import render,HttpResponse,redirect
from django.views import View #CBV写法中需要导入View
# Create your views here.
class LoginView(View):
def get(self,request):
return render(request, 'login.html')
def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'admin' and pwd == 'admin':
# return HttpResponse('登陆成功')
return redirect('/home/')
else:
# return HttpResponse('登陆失败')
return redirect('/login/')
CBV中源码重点
def dispatch(self, request, *args, **kwargs): #根据请求方法去分发对应的类发放来执行
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) #反射!!!!
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
CBV中重写dispatch方法
class LoginView(View):
def dispatch(self, request, *args, **kwargs):
print(111)
# print(request.META) #http所有相关请求头信息
ret = super().dispatch(request, *args, **kwargs) #render(request, 'login.html')
print(222)
return ret
def get(self,request):
print('this is get method!!!')
return render(request, 'login.html')
def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'admin' and pwd == 'admin':
return redirect('/home/')
else:
return redirect('/login/')
3.4.3 FBV
FBV中url写法
url(r'^login/', views.login),
#url(r'^login/', views.LoginView.as_view()),
FBV中views写法
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
uname = request.POST.get('uname')
pwd = request.POST.get('pwd')
if uname == 'admin' and pwd == 'admin':
# return HttpResponse('登陆成功')
return redirect('/home/')
else:
# return HttpResponse('登陆失败')
return redirect('/login/')
3.4.4 CBV和FBV的装饰器
def func(f):
def foo(request):
print(111)
ret = f(request)
print(222)
return ret
return foo
#FBV 模式下,和普通函数加装饰器是一样的写法
@func
def home(request):
print('home')
return HttpResponse('你懂什么是装饰器吗?')
CBV加装饰的三个姿势:
# @method_decorator(func,name='get') 位置3
class LoginView(View):
# @method_decorator(func) #位置2
def dispatch(self, request, *args, **kwargs):
print('aaaa')
ret = super().dispatch(request, *args, **kwargs) #render(request, 'login.html')
print('bbbb')
return ret
@method_decorator(func) #位置1
def get(self,request):
print('this is get method!!!')
return render(request, 'login.html')
def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'admin' and pwd == 'admin':
return redirect('/home/')
else:
return redirect('/login/')